#region File Header
//-----------------------------------------------------------------------------
// Bricks' Bane
//
// Copyright (C) 2010 Julien Villers
// This program is distributed under the terms of the 
// GNU Lesser General Public License (LGPL).
// See Docs/lgpl.txt and Docs/gpl.txt
//
// This file is based on GameStateManagement sample (C) Microsoft.
//-----------------------------------------------------------------------------
#endregion

using Microsoft.Xna.Framework;
using SibLib.GameState;
using SibLib.Sound;

namespace BricksBane.Screens
{
    /// <summary>
    /// The main menu screen is the first thing displayed when the game starts up.
    /// </summary>
    sealed class MainMenuScreen : NestedMenuScreen
    {
        #region Initialization

        /// <summary>
        /// Constructor fills in the menu contents.
        /// </summary>
        public MainMenuScreen()
            : base("Bricks' Bane")
        {
            // Setup sound cues
            CueNameValid = "MenuValid";
            CueNameCancel = "MenuCancel";
            CueNameUpDown = "MenuUpDown";

            // Create our menu entries.
            NestedMenuEntry campaignMenuEntry = new NestedMenuEntry("Campaign", "Easy", "Medium", "Hard");
            NestedMenuEntry scoreAttackMenuEntry = new NestedMenuEntry("Score Attack", "Easy", "Medium", "Hard");
            NestedMenuEntry timeAttackMenuEntry = new NestedMenuEntry("Time Attack", "Easy", "Medium", "Hard");
            MenuEntry marathonMenuEntry = new MenuEntry("Marathon");
            MenuEntry optionsMenuEntry = new MenuEntry("Options");
            MenuEntry exitMenuEntry = new MenuEntry("Exit");

            // Hook up menu event handlers.
            campaignMenuEntry.ChildEntries[0].Selected += CampaignMenuEntrySelected;
            campaignMenuEntry.ChildEntries[1].Selected += CampaignMenuEntrySelected;
            campaignMenuEntry.ChildEntries[2].Selected += CampaignMenuEntrySelected;
            scoreAttackMenuEntry.ChildEntries[0].Selected += ScoreAttackMenuEntrySelected;
            scoreAttackMenuEntry.ChildEntries[1].Selected += ScoreAttackMenuEntrySelected;
            scoreAttackMenuEntry.ChildEntries[2].Selected += ScoreAttackMenuEntrySelected;
            timeAttackMenuEntry.ChildEntries[0].Selected += TimeAttackMenuEntrySelected;
            timeAttackMenuEntry.ChildEntries[1].Selected += TimeAttackMenuEntrySelected;
            timeAttackMenuEntry.ChildEntries[2].Selected += TimeAttackMenuEntrySelected;
            marathonMenuEntry.Selected += MarathonMenuEntrySelected;
            optionsMenuEntry.Selected += OptionsMenuEntrySelected;
            exitMenuEntry.Selected += OnCancel;

            // Add entries to the menu.
            MenuEntries.Add(campaignMenuEntry);
            MenuEntries.Add(scoreAttackMenuEntry);
            MenuEntries.Add(timeAttackMenuEntry);
            MenuEntries.Add(marathonMenuEntry);
            MenuEntries.Add(optionsMenuEntry);
            MenuEntries.Add(exitMenuEntry);
        }

        public override void LoadContent()
        {
            base.LoadContent();

            m_SoundManager.StartPlayList(new string[] { "SILENCE0", "TitleMusic", "SILENCE10"});      // Note: the 0 seconds silence is a workaround.
        }

        #endregion

        #region Handle Input

        /// <summary>
        /// Event handler for when the Play Game menu entry is selected.
        /// </summary>
        void CampaignMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            int idx = ((NestedMenuEntry)MenuEntries[0]).ChildEntries.IndexOf((MenuEntry)sender);
            LaunchGame(e.PlayerIndex, E_GameModes.Campaign, (E_GameDifficulties)idx);
        }

        /// <summary>
        /// Event handler for when the Play Game menu entry is selected.
        /// </summary>
        void ScoreAttackMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            int idx = ((NestedMenuEntry)MenuEntries[1]).ChildEntries.IndexOf((MenuEntry)sender);
            // TODO: sub menu to pickup level
            LaunchGame(e.PlayerIndex, E_GameModes.ScoreAttack, (E_GameDifficulties)idx);
        }

        /// <summary>
        /// Event handler for when the Play Game menu entry is selected.
        /// </summary>
        void TimeAttackMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            int idx = ((NestedMenuEntry)MenuEntries[2]).ChildEntries.IndexOf((MenuEntry)sender);
            // TODO: sub menu to pickup level
            LaunchGame(e.PlayerIndex, E_GameModes.TimeAttack, (E_GameDifficulties)idx);
        }

        /// <summary>
        /// Event handler for when the Play Game menu entry is selected.
        /// </summary>
        void MarathonMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            LaunchGame(e.PlayerIndex, E_GameModes.Marathon, E_GameDifficulties.Medium);
        }

        private void LaunchGame(PlayerIndex index, E_GameModes mode, E_GameDifficulties difficulty)
        {            
            LoadingScreen.Load(ScreenManager, true, index, new GameplayScreen(mode, difficulty));
        }

        /// <summary>
        /// Event handler for when the Options menu entry is selected.
        /// </summary>
        void OptionsMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            OptionsMenuScreen screen = new OptionsMenuScreen();
            CopyCueNamesTo(screen);
            ScreenManager.AddScreen(screen, e.PlayerIndex);
        }

        /// <summary>
        /// When the user cancels the main menu, ask if they want to exit the sample.
        /// </summary>
        protected override void OnCancel(PlayerIndex playerIndex)
        {
            const string message = "Are you sure you want to exit Bricks' Bane?";

            MessageBoxScreen confirmExitMessageBox = new MessageBoxScreen(message);

            confirmExitMessageBox.Accepted += ConfirmExitMessageBoxAccepted;

            ScreenManager.AddScreen(confirmExitMessageBox, playerIndex);
        }

        /// <summary>
        /// Event handler for when the user selects ok on the "are you sure
        /// you want to exit" message box.
        /// </summary>
        void ConfirmExitMessageBoxAccepted(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.Game.Exit();
        }


        #endregion
    }
}
